<template>
  <div>
    <!-- 使用自定义布局组件 NuxtLayout 设置页面上方的工具栏，传递标题和图标属性 -->
    <NuxtLayout
      name="top-tool"
      title="EDIT"
      icon="bi-body-text"
    ></NuxtLayout>

    <!-- 主要内容 -->
    <div class="main-box m-2 secondly-color uni-shadow">
      <div v-if="isLoadingComplete">
        <!-- 顶部控制栏 -->
        <!-- <div class="h-10"></div> -->
        <!-- 标题栏 -->
        <div
          class="h-12 w-full"
          style="
            background-color: var(--bg-secondly);
            border: 1px solid var(--color-10);
          "
        >
          <UniWhiteInput
            style="width: 100%; height: 100%"
            v-model:model-value="articleBuffer.Title"
          ></UniWhiteInput>
        </div>
        <!-- 编辑区域 -->
        <MdEditor
          id="editor"
          :editorId="editorId"
          v-model="articleBuffer.Content"
          :theme="editorTheme"
          style="height: 80vh"
        ></MdEditor>
      </div>
      <!-- 未加载完成时的骨架框 -->
      <div
        v-else
        class="p-4"
      >
        <el-skeleton
          animated
          :rows="18"
        />
      </div>
    </div>
    <!-- 选项盒子 -->
    <div
      id="options-box"
      class="secondly-color p-2 uni-shadow"
    >
      <div v-if="isLoadingComplete">
        <!-- 分割线 -->
        <ElDivider content-position="left"> 信息统计 </ElDivider>
        <!-- 表单 -->
        <ElForm
          labelWidth="130px"
          ref="formRef"
          :model="articleBuffer"
          :rules="formRules"
        >
          <!-- 文章标题 -->
          <ElFormItem
            label="文章标题"
            prop="Title"
          >
            <ElInput v-model="articleBuffer.Title"></ElInput>
          </ElFormItem>
          <!-- 文章简介 -->
          <ElFormItem
            label="文章简介"
            prop="Synopsis"
          >
            <ElInput
              v-model="articleBuffer.Synopsis"
              placeholder="文章简介..."
              type="textarea"
            ></ElInput>
          </ElFormItem>
          <!-- 文章标签 -->
          <ElFormItem label="文章标签">
            <!-- 标签盒子 -->
            <div class="flex gap-2">
              <!-- 标签 -->
              <ElTag
                v-for="item in articleBuffer.Tags"
                @close="removeTagHandle(item)"
                :disable-transitions="false"
                closable
                >{{ item }}</ElTag
              >
              <!-- <input v-if="isShowAddTagInput" /> -->
              <ElInput
                ref="inputRef"
                v-if="isShowAddTagInput"
                size="small"
                style="width: 4rem"
                v-model="inputTagBuffer"
                @blur="inputConfirmHandle"
                @keyup.enter="inputConfirmHandle"
              ></ElInput>
              <!-- 点击显示输入 -->
              <ElButton
                v-else
                @click="showAddTagHandle"
                size="small"
                >添加Tag</ElButton
              >
            </div>
          </ElFormItem>
          <!-- 封面图片 -->
          <ElFormItem label="文章封面">
            <div
              class="w-full flex gap-4"
              style="height: 200px"
            >
              <!-- 文件上传 -->
              <div style="flex: 1">
                <el-upload
                  drag
                  multiple
                  :action="API.BASE + API.FILE_UPLOAD.URL"
                  v-model:file-list="uploadPictureList"
                  :headers="authHeaders()"
                  :limit="1"
                  :before-upload="pictureUploadBeforeHandle"
                  @success="pictureUploadSuccessHandle"
                  @error="pictureUploadErrorHandle"
                >
                  <div
                    class="text-ellipsis overflow-hidden whitespace-nowrap opacity-50"
                  >
                    拖入以上传封面图片
                  </div>
                </el-upload>
              </div>
              <!-- 封面图片 -->
              <div
                style="flex: 3; height: 100%"
                class="rounded-lg overflow-hidden"
              >
                <UniCosImage
                  class="w-h-full"
                  :format="CosImgFormatSuffix.WEBP"
                  :src="articleBuffer.PictureUrl"
                ></UniCosImage>
                <!-- <ElImage
                  :src="articleBuffer.PictureUrl"
                  class="w-h-full"
                  fit="cover"
                ></ElImage> -->
              </div>
            </div>
          </ElFormItem>
          <!-- 表单项 -->
          <ElFormItem label="文章附件">
            <div class="w-full flex">
              <el-upload
                style="width: 100%"
                drag
                multiple
                :action="API.BASE + API.FILE_UPLOAD.URL"
                v-model:file-list="uploadFileList"
                :headers="authHeaders()"
                :on-success="fileUploadSuccesHandle"
                :on-error="fileUploadErrorHandle"
                :on-remove="removeFileHandle"
              >
                <div
                  class="text-ellipsis overflow-hidden whitespace-nowrap opacity-50"
                >
                  拖入以上传文章附件
                </div>
              </el-upload>
            </div>
          </ElFormItem>
        </ElForm>
        <!-- 底部按钮区域 -->
        <div
          style="width: 100%"
          class="flex items-end justify-end pr-16"
        >
          <ElButton
            type="danger"
            @click="onClickClear"
            >清除博客</ElButton
          >
          <ElButton
            v-loading.fullscreen.lock="isLoading"
            type="primary"
            @click="() => (isModify ? onClickModify() : onClickPublish())"
            >{{ isModify ? "确认修改" : "发布博客" }}</ElButton
          >
        </div>
      </div>
      <!-- 未加载时渲染 -->
      <div
        v-else
        class="p-4"
      >
        <el-skeleton
          animated
          :rows="8"
        ></el-skeleton>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import type {
  FormInstance,
  FormRules,
  InputInstance,
  UploadFile,
  UploadFiles,
  UploadRawFile,
  UploadUserFile,
} from "element-plus";
import "md-editor-v3/lib/style.css";
import { API } from "~/models/api";
import { MdCatalog, MdEditor, ModalToolbar, type Themes } from "md-editor-v3";
import type { ArticleCreateRequest, ArticleResponse } from "~/models/article";
import type { FileResponse } from "~/models/file";
import type { ResponseMsg } from "~/models/universal";
import { CosImgFormatSuffix } from "~/models/cos";
import { FaLessThanEqual } from "oh-vue-icons/icons";
const isLoading = ref(false);
const isDark = useDark();
const editorId = ref("EditEditor");
const isShowAddTagInput = ref(false);
const inputRef = ref<InputInstance>();
const inputTagBuffer = ref("");
const isLoadingComplete = ref(false);
const isModify = ref(false);
const route = useRoute();

// 编辑器方案
const editorTheme = ref<Themes>("dark");
if (isDark.value) {
  editorTheme.value = "dark";
} else editorTheme.value = "light";

const articleBuffer = ref<ArticleCreateRequest>({
  Title: "",
  Content: "",
  Synopsis: "",
  PictureUrl: "",
  Tags: [],
  ViewLevel: 0,
  FileIds: [],
});

const uploadPictureList = ref<UploadUserFile[]>([]);
const uploadFileList = ref<UploadUserFile[]>([]);

// 点击清除
const onClickClear = () => {
  articleBuffer.value = {
    Title: "",
    Content: "",
    Synopsis: "",
    PictureUrl: "",
    Tags: [],
    ViewLevel: 0,
    FileIds: [],
  };
  uploadPictureList.value = [];
  uploadFileList.value = [];
};
// 点击发布
const onClickPublish = async () => {
  if (!(await validForm())) {
    createSimpleElNotification(false, "信息缺少");
    return;
  }

  isLoading.value = true;
  const response = await $fetch<ResponseMsg<boolean>>("/api/article/create", {
    headers: authHeaders(),
    body: articleBuffer.value,
    method: "POST",
  });
  ElNotification({
    type: !!response.status ? "success" : "error",
    message: response.msg,
    duration: 2000,
    showClose: false,
  });
  if (!!response.status) useRouter().back();
  isLoading.value = false;
};
// 点击修改
const onClickModify = async () => {
  if (!(await validForm())) {
    createSimpleElNotification(false, "信息缺少");
    return;
  }

  isLoading.value = true;
  let tempArticleBuffer = articleBuffer.value as any;
  delete tempArticleBuffer.ViewLevel;
  const response = await $fetch<ResponseMsg<boolean>>("/api/article/modify", {
    headers: authHeaders(),
    body: {
      mode: "",
      args: {
        ...tempArticleBuffer,
        payload: route.params.id,
      },
    },
    method: "POST",
  });

  ElNotification({
    type: !!response.status ? "success" : "error",
    message: response.msg,
    duration: 2000,
    showClose: false,
  });
  isLoading.value = false;
};

// 封面上传成功处理者
const pictureUploadSuccessHandle = (
  response: ResponseMsg<FileResponse>,
  uploadFile: UploadFile,
  uploadFiles: UploadFiles
) => {
  createSimpleElNotification(
    !!response.status,
    !!response.status ? "封面上传成功" : "封面上传失败"
  );
  articleBuffer.value.PictureUrl = response.data.cosUrl;
  uploadPictureList.value = [];
};
// 封面上传失败处理者
const pictureUploadErrorHandle = () => {};
// 封面上传前处理者 这里是针对文件上传前做一次类型检查
const pictureUploadBeforeHandle = (uploadFile: UploadRawFile) => {
  if (uploadFile.type.split("/")[0] != "image") {
    createSimpleElNotification(false, `上传封面类型错误: ${uploadFile.type}`);
    return false;
  } else {
    return true;
  }
};
// 文件上传成功处理
const fileUploadSuccesHandle = (
  response: ResponseMsg<FileResponse>,
  uploadFile: UploadFile,
  uploadFiles: UploadFiles
) => {
  articleBuffer.value.FileIds.push(response.data.id);
};
// 文件上传失败处理
const fileUploadErrorHandle = (
  error: Error,
  uploadFile: UploadFile,
  uploadFiles: UploadFiles
) => {
  createSimpleElNotification(false, error.message);
};
// 移除文件处理
const removeFileHandle = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  let response: ResponseMsg<FileResponse> =
    uploadFile.response as ResponseMsg<FileResponse>;
  let itemIndex = articleBuffer.value.FileIds.indexOf(response.data.id);
  articleBuffer.value.FileIds.splice(itemIndex, 1);
};

// 显示添加标签处理者
const showAddTagHandle = () => {
  isShowAddTagInput.value = true;
  nextTick(() => {
    inputRef.value!.input!.focus();
  });
};
// 输入确认处理者
const inputConfirmHandle = () => {
  if (inputTagBuffer.value) articleBuffer.value.Tags.push(inputTagBuffer.value);
  isShowAddTagInput.value = false;
  inputTagBuffer.value = "";
};
// 删除标签处理者
const removeTagHandle = (tag: string) => {
  articleBuffer.value.Tags.splice(articleBuffer.value.Tags.indexOf(tag), 1);
};

// 监听颜色变化，以切换编辑器颜色模式
watch(isDark, (newVal, oldVal) => {
  // console.log(newVal);
  if (newVal) editorTheme.value = "dark";
  else editorTheme.value = "light";
});

/**
 * 表单验证方案
 *
 */

const formRef = ref<FormInstance>();
const formRules = reactive<FormRules<ArticleCreateRequest>>({
  Title: [
    { required: true, message: "缺失标题...", trigger: "blur" },
    { min: 4, max: 20, message: "标题长度限制在4到20之间", trigger: "blur" },
  ],
  Synopsis: [
    {
      required: true,
      message: "缺失文章简介...",
      trigger: "change",
    },
  ],
});

const validForm = async (): Promise<boolean> => {
  if (!formRef.value) return false;
  let isValid = false;
  await formRef.value.validate((valid) => {
    if (valid) {
      isValid = true;
    } else {
      isValid = false;
    }
  });
  return isValid;
};

onMounted(async () => {
  // console.log(route.params);
  if (route.params.id == "0") {
    isModify.value = false;
  } else {
    isModify.value = true;
  }

  // TODO:这里如果是修改 则请求数据
  if (isModify.value) {
    const modifyResponse = await $fetch<ResponseMsg<ArticleResponse>>(
      "/api/article/queryDetail",
      {
        method: "post",
        body: {
          mode: "id",
          args: {
            payload: route.params.id,
          },
        },
      }
    );

    if (modifyResponse.data == null || !modifyResponse.status) {
      createSimpleElNotification(false, "文章不存在...默认重新创建文章...");
      isModify.value = false;
    } else {
      //TODO: 这里标题图片没有上传进去 需要调整一下

      articleBuffer.value.Content = modifyResponse.data.content ?? "";
      articleBuffer.value.FileIds = modifyResponse.data.fileIds ?? [];
      articleBuffer.value.Synopsis = modifyResponse.data.synopsis ?? "";
      articleBuffer.value.PictureUrl = modifyResponse.data.pictureUrl ?? "";
      articleBuffer.value.Tags = modifyResponse.data.tags ?? [];
      articleBuffer.value.Title = modifyResponse.data.title ?? "";
      articleBuffer.value.ViewLevel = modifyResponse.data.viewLevel ?? 0;
    }
  }

  await nextTick();
  isLoadingComplete.value = true;
});

definePageMeta({
  middleware: ["auth"],
  layout: false,
});
</script>

<style lang="scss" scoped>
.main-box {
  margin-left: auto;
  margin-right: auto;
  border-radius: 0.5vmin;
  width: clamp(640px, 80vw, 1400px);
  min-width: 640px;
}

#options-box {
  margin-left: auto;
  margin-right: auto;
  width: clamp(640px, 80vw, 1400px);
}

#toolBar {
  height: 50px;
  position: fixed;
  bottom: 0px;
  width: 100vw;
  min-width: 640px;

  // background-color: red;
}

// :deep(.el-input__wrapper) {
//   border: none;
//   box-shadow: none;
//   border-radius: 0px;
//   border-bottom: 1px solid var(--color-10);
// }

// :deep(.el-input__wrapper:hover) {
//   border: none;
//   box-shadow: none;
//   // border-bottom: 1px solid var(--color-100);
// }

// :deep(.is-focus) {
//   // background-color: rgba($color: #000000, $alpha: 1);
//   border: none;
//   box-shadow: none;
//   // border-bottom: 1px solid var(--color-80);
// }
</style>
